package com.upb.webserver.user;

import cn.hutool.core.collection.CollectionUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.upb.webserver.application.ApplicationManager;
import com.upb.webserver.common.pojo.base.BasePageResponse;
import com.upb.webserver.common.pojo.base.BaseResponse;
import com.upb.webserver.common.pojo.rest.fisco.chainmgr.req.ReqNewUser;
import com.upb.webserver.common.pojo.rest.fisco.data.resp.UserInfo;
import com.upb.webserver.common.pojo.user.ReqAddUserVO;
import com.upb.webserver.common.pojo.user.RspUserVO;
import com.upb.webserver.common.returncode.ConstantCode;
import com.upb.webserver.common.tools.JsonUtils;
import com.upb.webserver.dao.entity.TbApplication;
import com.upb.webserver.rest.fisco.FiscoChainMgrRestService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class FiscoUserService implements BaseUserService {
    @Autowired
    private ApplicationManager applicationManager;
    @Autowired
    private FiscoChainMgrRestService fiscoChainMgrRestService;

    /**
     * @param param
     * @return
     */
    @Override
    public BaseResponse createNewUser(ReqAddUserVO param) {
        log.info("start createNewUser  param:{}", JsonUtils.objToString(param));

        TbApplication application = applicationManager.verifyApplicationId(param.getApplicationId());

        ReqNewUser reqNewUser = new ReqNewUser();
        BeanUtils.copyProperties(param, reqNewUser);
        reqNewUser.setAppId(application.getFinalName());
        reqNewUser.setSignUserName(param.getUserName());

        log.info("reqNewUser:{}", JsonUtils.objToString(reqNewUser));
        return fiscoChainMgrRestService.newUser(reqNewUser);
    }

    @Override
    public BasePageResponse listUserByApplication(int applicationId, int pageNumber, int pageSize) {
        log.info("start listUserByApplication application:{} pageNumber:{} pageSize:{}", applicationId, pageNumber, pageSize);

        TbApplication application = applicationManager.verifyApplicationId(applicationId);
        Pair<Integer, List<UserInfo>> userRestRspPair = fiscoChainMgrRestService.userList(application.getFinalName(), pageNumber, pageSize);

        if (CollectionUtils.isEmpty(userRestRspPair.getValue()))
            return BasePageResponse.initialize();

        List<RspUserVO> rspUserList = new ArrayList<>();
        for (UserInfo rspUserDTO : userRestRspPair.getValue())
            rspUserList.add(convertToRspUserVO(rspUserDTO));

        BasePageResponse basePageResponse = new BasePageResponse(ConstantCode.SUCCESS);
        basePageResponse.setTotalCount(userRestRspPair.getLeft());
        basePageResponse.setData(rspUserList);

        log.info("finish listUserByApplication result:{}", JsonUtils.objToString(basePageResponse));
        return basePageResponse;
    }

    /**
     * query user by page
     *
     * @param param
     * @return
     */
    @Override
    public BasePageResponse queryUserPage(Map<String, Object> param) {
        BasePageResponse restResponse = fiscoChainMgrRestService.queryUserByPage(param);
        log.info("restResponse:{}", JsonUtils.objToString(restResponse));

        if (restResponse.getTotalCount() <= 0)
            return restResponse;


        List<UserInfo> list = JsonUtils.stringToObj(JsonUtils.objToString(restResponse.getData()),
                new TypeReference<List<UserInfo>>() {
                });

        List<RspUserVO> rspUserList = CollectionUtil.emptyIfNull(list)
                .stream()
                .map(u -> convertToRspUserVO(u))
                .collect(Collectors.toList());
        restResponse.setData(rspUserList);

        log.info("finish listUserByApplication result:{}", JsonUtils.objToString(restResponse));
        return restResponse;
    }


    /**
     * @param rspUserDTO
     * @return
     */
    private RspUserVO convertToRspUserVO(UserInfo rspUserDTO) {
        log.debug("start convertToRspUserVO  rspUserDTO:{}", JsonUtils.objToString(rspUserDTO));
        if (null == rspUserDTO) return null;

        TbApplication tbApplication = applicationManager.verifyApplicationId(rspUserDTO.getGroupId());
        RspUserVO rspUserVO = new RspUserVO();
        BeanUtils.copyProperties(rspUserDTO, rspUserVO);
        rspUserVO.setApplicationId(rspUserDTO.getGroupId());
        rspUserVO.setApplicationName(tbApplication.getName());
        rspUserVO.setApplicationNameZh(tbApplication.getNameZh());
        rspUserVO.setUuid(rspUserDTO.getSignUserId());
        rspUserVO.setUserName(rspUserDTO.getSignUserName());
        return rspUserVO;
    }
}
